package com.soxing.braindata.web.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.soxing.braindata.common.util.AesUtil;
import com.soxing.braindata.dao.domain.request.ResearchSearchRequest;
import com.soxing.braindata.dao.domain.vo.JumpInfo;
import com.soxing.braindata.dao.entity.*;
import com.soxing.braindata.dao.service.IResearchService;
import com.soxing.braindata.dao.service.ISiteService;
import com.soxing.braindata.dao.service.ITesteeService;
import com.soxing.braindata.domain.constants.SystemConstant;
import com.soxing.braindata.domain.response.TokenResponse;
import com.soxing.braindata.domain.rpc.OriginSite;
import com.soxing.braindata.domain.rpc.OriginSubject;
import com.soxing.braindata.domain.rpc.Token;
import com.soxing.braindata.domain.vo.UserVo;
import com.soxing.braindata.service.manager.ISiteManager;
import com.soxing.braindata.service.manager.ITesteeManager;
import com.soxing.braindata.service.manager.IUserManager;
import com.soxing.braindata.service.sync.ISyncService;
import com.soxing.common.utils.response.WebResponse;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.SignatureException;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.List;
import java.util.regex.Pattern;
import java.util.regex.Matcher;

@Slf4j
@RestController
public class JumpController {
    @Resource
    private ISiteManager siteManager;
    @Resource
    private ISiteService siteService;
    @Resource
    private ISyncService<OriginSite> syncSiteService;
    @Resource
    private IUserManager userManager;
    @Resource
    private ITesteeService testeeService;

    @Resource
    private IResearchService researchService;

    private static final String SECRET_KEY = "BeiYiEEG"; // 应该是安全且随机生成的
    private static final long EXPIRATION_TIME = 864_000_000; // 10天

    @PostMapping("/encode")
    @ApiOperation(value = "编码测试")
    public TokenResponse encode(@RequestParam String data, HttpServletRequest request) throws Exception {
        String aesKey = "y1dUx2Ktl01rxjmS";
        String userAccount = AesUtil.encrypt(data,aesKey);
        String userAccountStr = java.net.URLEncoder.encode(userAccount,"UTF-8");
        return TokenResponse.success(userAccountStr);
    }

    @PostMapping("/getToken")
    @ApiOperation(value = "获取临时token")
    public TokenResponse getToken(@RequestBody Token obj, HttpServletRequest request) throws Exception {
        log.info("---------获取token----------");
        log.info("userAccount: "+obj.getUserAccount());
        String userAccount = obj.getUserAccount();
        String userAccountStr = java.net.URLDecoder.decode(userAccount,"UTF-8");
        String aesKey = "y1dUx2Ktl01rxjmS";
        String userAccountOrigin = AesUtil.decrypt(userAccountStr,aesKey);
        UserVo user = userManager.getUserVo(userAccountOrigin);
        if(user != null){
            String token = Jwts.builder()
                    .setSubject(userAccountOrigin)
                    .setIssuedAt(new Date())
                    .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
                    .signWith(SignatureAlgorithm.HS512, SECRET_KEY)
                    .compact();
            token = token.replaceAll("_","#&/");
            return TokenResponse.success(token);
        }else{
            return TokenResponse.fail();
        }
    }

    @PostMapping("/validateToken")
    @ApiOperation(value = "验证临时token")
    public WebResponse<JumpInfo> validateToken(@RequestParam String paraStr, HttpServletRequest request) throws Exception {
        try {
            log.info("---------跳转----------");
            log.info("paraStr: " + paraStr);
//            String paraStr1 = java.net.URLDecoder.decode(paraStr, "UTF-8");
            String aesKey = "y1dUx2Ktl01rxjmS";
            String paraStrOrigin = AesUtil.decrypt(paraStr, aesKey);
            String[] para = paraStrOrigin.split("_");
//        Pattern pattern = Pattern.compile("([^_]+)_([^_]+)_([^_]+)_([^_]+)_([^_]+)_([^_]+)_([^_]+)_([^_]+)_([^_]+)");
//        Matcher matcher = pattern.matcher(paraStrOrigin);
            JumpInfo info = new JumpInfo();
            Boolean flag;
            try {
                Claims claims = Jwts.parser()
                        .setSigningKey(SECRET_KEY)
                        .parseClaimsJws(para[0].replaceAll("#&/", "_"))
                        .getBody();
                flag = claims.getExpiration().after(new Date());
            } catch (SignatureException e) {
                // 签名异常处理
                flag = false;
            }
            if (flag) {
                info.setToken(para[0].replaceAll("#&/", "_"));
                info.setUserNum(para[1].replaceAll("#&/", "_"));
                info.setTesteeNo(para[2]);
                info.setSubjectCode(para[3]);
                info.setSectionType(para[4]);
                info.setSectionCode(para[5]);
                info.setVisitNum(para[6]);
                info.setEntranceFlag(para[7]);
                Research result;
                result = researchService.getOne(new LambdaQueryWrapper<Research>().eq(Research::getSubjectCode, info.getSubjectCode()));
                if (result != null) {
                    info.setSubjectPkId(result.getSubjectPkId());
                    UserVo userVo = userManager.getUserVo(info.getUserNum());
                    if (userVo != null) {
                        request.getSession().setAttribute(SystemConstant.LOGIN_USER, userVo);
                        info.setRoleList(userVo.getRoleList());
                        info.setUserType(userVo.getUserType());
                        if(info.getTesteeNo().length() > 0){
                            List<Testee> list = testeeService.list(new LambdaQueryWrapper<Testee>().eq(Testee::getTesteeNo, info.getTesteeNo()));
                            if (list.size() > 0){
                                Testee testee = list.get(0);
                                info.setTesteeId(testee.getId());
                                return WebResponse.success(info);
                            }else {
                                return WebResponse.fail();
                            }
                        }else {
                            return WebResponse.success(info);
                        }
                    } else {
                        return WebResponse.fail();
                    }
                } else {
                    return WebResponse.fail();
                }
            } else {
                return WebResponse.fail();
            }
        }catch (SignatureException e) {
            return WebResponse.fail();
        }
    }
}
